<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Redis监控面板</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 20px;
            background-color: #f5f5f5;
        }
        .container {
            max-width: 1200px;
            margin: 0 auto;
        }
        .header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 20px;
            border-radius: 10px;
            margin-bottom: 20px;
            text-align: center;
        }
        .status-card {
            background: white;
            border-radius: 10px;
            padding: 20px;
            margin-bottom: 20px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        .status-indicator {
            display: inline-block;
            width: 12px;
            height: 12px;
            border-radius: 50%;
            margin-right: 8px;
        }
        .status-healthy {
            background-color: #28a745;
        }
        .status-unhealthy {
            background-color: #dc3545;
        }
        .status-error {
            background-color: #ffc107;
        }
        .grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
            gap: 20px;
            margin-bottom: 20px;
        }
        .metric-card {
            background: white;
            border-radius: 10px;
            padding: 20px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        .metric-title {
            font-size: 14px;
            color: #666;
            margin-bottom: 10px;
        }
        .metric-value {
            font-size: 24px;
            font-weight: bold;
            color: #333;
        }
        .btn {
            background: #007bff;
            color: white;
            border: none;
            padding: 10px 20px;
            border-radius: 5px;
            cursor: pointer;
            margin: 5px;
            font-size: 14px;
        }
        .btn:hover {
            background: #0056b3;
        }
        .btn-success {
            background: #28a745;
        }
        .btn-success:hover {
            background: #1e7e34;
        }
        .btn-danger {
            background: #dc3545;
        }
        .btn-danger:hover {
            background: #c82333;
        }
        .log-container {
            background: #1e1e1e;
            color: #fff;
            padding: 15px;
            border-radius: 5px;
            font-family: 'Courier New', monospace;
            font-size: 12px;
            max-height: 300px;
            overflow-y: auto;
        }
        .log-entry {
            margin-bottom: 5px;
            padding: 2px 0;
        }
        .log-info {
            color: #17a2b8;
        }
        .log-error {
            color: #dc3545;
        }
        .log-warning {
            color: #ffc107;
        }
        .log-success {
            color: #28a745;
        }
        .refresh-btn {
            position: fixed;
            top: 20px;
            right: 20px;
            background: #28a745;
            color: white;
            border: none;
            padding: 10px 15px;
            border-radius: 50%;
            cursor: pointer;
            font-size: 18px;
        }
        .auto-refresh {
            margin: 10px 0;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>🔴 Redis监控面板</h1>
            <p>实时监控Redis连接状态和性能指标</p>
        </div>

        <button class="refresh-btn" onclick="refreshAll()" title="刷新所有数据">🔄</button>

        <div class="auto-refresh">
            <label>
                <input type="checkbox" id="autoRefresh" onchange="toggleAutoRefresh()"> 自动刷新 (每5秒)
            </label>
        </div>

        <div class="status-card">
            <h3>
                <span id="statusIndicator" class="status-indicator status-error"></span>
                Redis连接状态
            </h3>
            <div id="statusContent">正在检查连接状态...</div>
            <button class="btn" onclick="checkHealth()">检查健康状态</button>
        </div>

        <div class="grid">
            <div class="metric-card">
                <div class="metric-title">Redis版本</div>
                <div id="redisVersion" class="metric-value">-</div>
            </div>
            <div class="metric-card">
                <div class="metric-title">连接客户端数</div>
                <div id="connectedClients" class="metric-value">-</div>
            </div>
            <div class="metric-card">
                <div class="metric-title">内存使用</div>
                <div id="usedMemory" class="metric-value">-</div>
            </div>
            <div class="metric-card">
                <div class="metric-title">总命令数</div>
                <div id="totalCommands" class="metric-value">-</div>
            </div>
            <div class="metric-card">
                <div class="metric-title">运行时间</div>
                <div id="uptime" class="metric-value">-</div>
            </div>
            <div class="metric-card">
                <div class="metric-title">响应时间</div>
                <div id="responseTime" class="metric-value">-</div>
            </div>
        </div>

        <div class="status-card">
            <h3>Redis操作测试</h3>
            <button class="btn" onclick="testOperation('set')">测试写入</button>
            <button class="btn" onclick="testOperation('get')">测试读取</button>
            <button class="btn" onclick="testOperation('delete')">测试删除</button>
            <div id="testResult"></div>
        </div>

        <div class="status-card">
            <h3>操作日志</h3>
            <div id="logContainer" class="log-container">
                <div class="log-entry log-info">[INFO] 监控面板已启动</div>
            </div>
        </div>
    </div>

    <script>
        let autoRefreshInterval;
        const baseUrl = 'http://localhost:8080/api/redis';

        // 页面加载时初始化
        document.addEventListener('DOMContentLoaded', function() {
            refreshAll();
        });

        // 切换自动刷新
        function toggleAutoRefresh() {
            const checkbox = document.getElementById('autoRefresh');
            if (checkbox.checked) {
                autoRefreshInterval = setInterval(refreshAll, 5000);
                addLog('自动刷新已启用', 'info');
            } else {
                clearInterval(autoRefreshInterval);
                addLog('自动刷新已禁用', 'info');
            }
        }

        // 刷新所有数据
        async function refreshAll() {
            await checkHealth();
            await getStats();
        }

        // 检查健康状态
        async function checkHealth() {
            try {
                const startTime = Date.now();
                const response = await fetch(`${baseUrl}/health`);
                const data = await response.json();
                const responseTime = Date.now() - startTime;

                updateStatusIndicator(data.data.status);
                updateStatusContent(data.data);
                updateResponseTime(responseTime);

                if (data.code === 200) {
                    addLog(`健康检查通过 - 写入: ${data.data.writeTime}, 读取: ${data.data.readTime}`, 'success');
                } else {
                    addLog(`健康检查失败: ${data.message}`, 'error');
                }
            } catch (error) {
                updateStatusIndicator('error');
                updateStatusContent({ message: '连接失败: ' + error.message });
                addLog(`健康检查异常: ${error.message}`, 'error');
            }
        }

        // 获取统计信息
        async function getStats() {
            try {
                const response = await fetch(`${baseUrl}/stats`);
                const data = await response.json();

                if (data.code === 200) {
                    updateMetrics(data.data);
                    addLog('统计信息更新成功', 'info');
                } else {
                    addLog(`获取统计信息失败: ${data.message}`, 'error');
                }
            } catch (error) {
                addLog(`获取统计信息异常: ${error.message}`, 'error');
            }
        }

        // 测试Redis操作
        async function testOperation(operation) {
            try {
                const formData = new FormData();
                formData.append('operation', operation);

                const response = await fetch(`${baseUrl}/test`, {
                    method: 'POST',
                    body: formData
                });

                const data = await response.json();
                const resultDiv = document.getElementById('testResult');

                if (data.code === 200) {
                    resultDiv.innerHTML = `<div style="color: green; margin-top: 10px;">✅ ${data.data.message}</div>`;
                    addLog(`${operation}操作测试成功`, 'success');
                } else {
                    resultDiv.innerHTML = `<div style="color: red; margin-top: 10px;">❌ ${data.message}</div>`;
                    addLog(`${operation}操作测试失败: ${data.message}`, 'error');
                }
            } catch (error) {
                document.getElementById('testResult').innerHTML = 
                    `<div style="color: red; margin-top: 10px;">❌ 测试失败: ${error.message}</div>`;
                addLog(`${operation}操作测试异常: ${error.message}`, 'error');
            }
        }

        // 更新状态指示器
        function updateStatusIndicator(status) {
            const indicator = document.getElementById('statusIndicator');
            indicator.className = 'status-indicator';
            
            switch (status) {
                case 'healthy':
                    indicator.classList.add('status-healthy');
                    break;
                case 'unhealthy':
                    indicator.classList.add('status-unhealthy');
                    break;
                default:
                    indicator.classList.add('status-error');
            }
        }

        // 更新状态内容
        function updateStatusContent(data) {
            const content = document.getElementById('statusContent');
            content.innerHTML = `
                <p><strong>状态:</strong> ${data.status || 'error'}</p>
                <p><strong>消息:</strong> ${data.message || '未知错误'}</p>
                ${data.writeTime ? `<p><strong>写入时间:</strong> ${data.writeTime}</p>` : ''}
                ${data.readTime ? `<p><strong>读取时间:</strong> ${data.readTime}</p>` : ''}
                <p><strong>时间戳:</strong> ${new Date(data.timestamp).toLocaleString()}</p>
            `;
        }

        // 更新指标
        function updateMetrics(data) {
            document.getElementById('redisVersion').textContent = data.redis_version || '-';
            document.getElementById('connectedClients').textContent = data.connected_clients || '-';
            document.getElementById('usedMemory').textContent = data.used_memory_human || '-';
            document.getElementById('totalCommands').textContent = data.total_commands_processed || '-';
            
            if (data.uptime_in_seconds) {
                const uptime = formatUptime(parseInt(data.uptime_in_seconds));
                document.getElementById('uptime').textContent = uptime;
            }
        }

        // 更新响应时间
        function updateResponseTime(time) {
            document.getElementById('responseTime').textContent = time + 'ms';
        }

        // 格式化运行时间
        function formatUptime(seconds) {
            const days = Math.floor(seconds / 86400);
            const hours = Math.floor((seconds % 86400) / 3600);
            const minutes = Math.floor((seconds % 3600) / 60);
            const secs = seconds % 60;

            let result = '';
            if (days > 0) result += days + '天';
            if (hours > 0) result += hours + '小时';
            if (minutes > 0) result += minutes + '分钟';
            result += secs + '秒';

            return result;
        }

        // 添加日志
        function addLog(message, type = 'info') {
            const logContainer = document.getElementById('logContainer');
            const timestamp = new Date().toLocaleTimeString();
            const logEntry = document.createElement('div');
            logEntry.className = `log-entry log-${type}`;
            logEntry.textContent = `[${timestamp}] ${message}`;
            
            logContainer.appendChild(logEntry);
            logContainer.scrollTop = logContainer.scrollHeight;

            // 限制日志条数
            if (logContainer.children.length > 100) {
                logContainer.removeChild(logContainer.firstChild);
            }
        }
    </script>
</body>
</html> 